package cn.dengta.webapp.user.vo;

import java.util.*;
import javax.annotation.Nullable;

import cn.dengta.common.model.APIResponse.Field;
import cn.dengta.common.model.Status;
import cn.dengta.common.model.ValueProxyImpl;
import cn.dengta.context.model.Country;
import cn.dengta.context.model.WesKit;
import cn.dengta.webapp.base.vo.UserIdEncode;
import cn.dengta.webapp.user.entity.ClientInfo;
import cn.dengta.webapp.user.entity.User;
import cn.dengta.webapp.user.entity.task.TaskRule;
import cn.dengta.webapp.user.model.Gender;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.codeplayer.util.*;

@Getter
@Setter
@Accessors(chain = true)
public class UserVO extends MemberVO<User> implements UserIdEncode {

	/** 前端展示使用 */
	private String uId;
	/** 备注名 */
	private String alias;
	/** 电视墙是否匿名：0=否，1=是 */
	@Field(name = "电视墙是否匿名", value = "0=否，1=是")
	private Integer tvAnonymous;
	/** VIP到期时间 */
	@Field(name = "VIP到期时间")
	private Date vipExpireTime;
	/** VIP每日赠送钻石是否领取：-1=不展示；0=否；1=是 */
	private Integer coinDay;
	/** 高级筛选:0=随机，1=头像认证 */
	@Field(name = "高级筛选", value = "0=随机，1=头像认证")
	private Integer advancedFilter;
	@Field(name = "年龄")
	private Integer age;
	@Field(name = "是否在线")
	public Boolean online;
	protected String session;
	protected String token, imToken;
	public Map<String, Object> userInfo;
	/** 是否关注 */
	@Field(name = "是否关注")
	public Boolean isFollowed;
	/** 是否关注 */
	@Field(name = "是否拉黑")
	public Boolean isBlock;
	@Field(name = "是否可取消拉黑")
	public Boolean canUnblock;
	/** 是否首次搭讪 */
	@Field(name = "是否首次搭讪")
	public Boolean isFirstChat;
	/** 是否可视频聊天 */
	@Field(name = "是否可视频聊天")
	public Boolean canVideoChat;
	/** 是否可添加相册 */
	@Field(name = "是否可添加相册")
	public Boolean canEditPhoto;
	/** 是否可编辑资料 */
	@Field(name = "是否可编辑资料")
	public Boolean canEditInfo;
	@Field(name = "需要设置头像")
	public Boolean needSetAvatar;
	@Field(name = "是否已修改过头像")
	public Boolean changedAvatar;
	@Field(name = "存在审核中头像")
	public Boolean avatarVerifying;
	public Boolean realNamed;
	/** 手机已认证 */
	public Boolean phoned;
	/** 已认证 */
	public Boolean avatared;
	/** 认证中 */
	public Boolean avataring;
	/** 来自注册 */
	public Boolean isRegister;
	public String constellation;
	@Field(name = "资料进度")
	public Integer supplyProgress;
	@Field(name = "偏好国家")
	public String likeCountry;
	public String language;
	public Map<String, Object> coin;
	public Map<String, Object> integral;
	/** 推广员管理开关 */
	public Boolean agentModelOpen;
	/** 邀请管理开关 */
	public Boolean inviteModelOpen;
	/** 邀请码开关 */
	public Boolean inviteModelSet;
	/** 好友数 */
	public String friendCount;
	public String followCount;
	public String fansCount;
	public Object photoVideo;
	/** 判断是否是系统充值 */
	private boolean rechargeSystem;

	/** 是否支付宝白名单：true=是；false=否； */
	public Boolean aliPayWhite;
	/** 同 aliPayWhite，用于审核规避关键字 */
	public Boolean air;

	/** 标签偏好（多个逗号隔开） */
	protected String likeTag;
	/** 最后活跃时间 */
	protected Long lastActive;

	public Long nowTime;
	/** 国家 */
	protected String country;
	protected Boolean needSetLikeLanguage;
	protected Boolean needSetLikeTag;
	protected Boolean needSetLikeGenre;
	/** 强制设置标签 */
	protected Boolean forceSetTag;
	@Field(name = "接通率")
	public Integer dialRate;
	/** 语言偏好缩写 */
	public String likeLanguageAbbr;
	/** 头像框 */
	public String avatarFrame;
	/** 用户等级 */
	public Integer userLevel;

	/** 真人认证：1=已认证；0=未认证 */
	protected Integer realPeople;
	/** 马甲ID */
	transient WesKit wesKit;

	/** 直播频道号 */
	public String channelName;
	/** 是否系统拉黑用户 */
	public Boolean sysBlack;
	/** 城市标识 */
	public Long areaId;
	/** 城市名称 */
	public String areaName;
	/** 标签数据 */
	//	public List<String> tags;
	/** 使用标签 */
	Object useTag;
	/** 亲密度 */
	private Integer intimacy;
	/** 图片集合 */
	private String images;
	/** 相册张数 */
	private Integer photoNum;
	/** 任务数据 */
	private List<TaskInfo> task;
	/** 推广员id */
	private Long agentId;

	/** 是否有 hot 标识 */
	public Boolean hots;
	/** 是否有女神勋章 */
	public Boolean goddess;

	public static UserVO from(@Nullable User source) {
		UserVO vo = copy(source, UserVO::new);
		vo.setUId(source.getId().toString());
		final long minActiveMs = System.currentTimeMillis() - User.onlineMaxDelayMs;
		vo.setOnline(Cmp.nullToZero(source.getLastActive()) > minActiveMs);
		vo.setAvatar(source.avatarOrDefault());
		return vo;
	}

	public void setAliPayWhiteForEnv(boolean verify, final boolean aliPayWhite) {
		if (verify) {
			this.air = aliPayWhite;
		} else {
			this.aliPayWhite = aliPayWhite;
		}
	}

	public boolean isNeedSetGender() {
		return gender == null;
	}

	public boolean isNewcomer() {
		return getSource().forNewcomer();
	}

	public boolean getHasAgent() {
		return X.isValid(getSource().getAgentId()) || getSource().isAgent();
	}

	@Override
	public Integer getGender() {
		return X.mapElse(gender, Gender::getValue, getSource().genderOrDefault().value);
	}

	public Integer getLikeGender() {
		return getSource().calcLikeGender();
	}

	public String getCertNo() {
		return getSource().getCertNo_();
	}

	@Override
	public String getAvatar() {
		return getSource().avatarOrDefault();
	}

	public boolean getVip() {
		return getSource().vip();
	}

	public String getLanguage() {
		User source = getSource();
		return source.hasChangeLanguage() ? source.getLanguage().alias : null;
	}

	public String getLikeNationalFlag() {
		return StringUtil.isEmpty(likeCountry) ? Country.GLOBAL_FLAG : X.map(Country.of(likeCountry), Country::getNationalShortFlag);
	}

	public Boolean getForceSetTag() {
		return getSource().forceSetTag();
	}

	@Override
	public Date getAddTime() {
		return super.getAddTime();
	}

	public String getNational() {
		return X.map(Country.of(country), Country::getLabel);
	}

	public String getNationalFlag() {
		return X.map(Country.of(country), Country::getNationalFlag);
	}

	public boolean getAbroad() {
		return true;
	}

	public Integer getLoginWay() {
		return X.map(getSource().getLoginWay(), ClientInfo.LoginWay::getValue);
	}

	public String getOnline_() {
		return online == null ? null : Status.of(online).getLabel();
	}

	public String getUId() {
		return id.toString();
	}

	@Getter
	@Setter
	public static class TaskInfo {

		/** 任务类型 */
		private TaskRule.TaskRuleType ruleType;
		/** 奖励 */
		private Integer coin;
		/** 是否完成 */
		private Boolean finish;

		public static TaskInfo of(TaskRule.TaskRuleType ruleType, Integer coin, Boolean finish) {
			TaskInfo info = new TaskInfo();
			info.setRuleType(ruleType);
			info.setCoin(coin);
			info.setFinish(finish);
			return info;
		}

		public String getRuleType_() {
			return ValueProxyImpl.label(ruleType);
		}

	}

}
